package com.canbot.u05.utils

import java.io.File
import java.io.FileInputStream
import java.io.FileNotFoundException
import java.io.IOException
import java.math.BigInteger
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
import java.security.DigestInputStream
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException

object Md5Utils {

    /**
     * 字符串 md5
     * @param str 需要进行 md5 的字符串
     * @return 字符串对应的 md5
     */
    fun md5(str: String): String? { //定义一个字节数组
        val secretBytes: ByteArray
        secretBytes = try { // 生成一个 MD5加密计算摘要
            val md = MessageDigest.getInstance("MD5")
            // 对字符串进行加密
            md.update(str.toByteArray())
            // 获得加密后的数据
            md.digest()
        } catch (e: NoSuchAlgorithmException) {
            throw RuntimeException("没有md5这个算法！")
        }
        // 将加密后的数据转换为16进制数字
        return bytes2HexString(secretBytes)
    }

    /**
     * Return the hex string of file's MD5 encryption.
     *
     * @param file The file.
     * @return the hex string of file's MD5 encryption
     */
    fun encryptMD5File2String(file: File?): String? {
        return bytes2HexString(encryptMD5File(file))
    }

    /**
     * Return the bytes of file's MD5 encryption.
     *
     * @param file The file.
     * @return the bytes of file's MD5 encryption
     */
    fun encryptMD5File(file: File?): ByteArray? {
        if (file == null) return null
        var fis: FileInputStream? = null
        val digestInputStream: DigestInputStream
        return try {
            fis = FileInputStream(file)
            var md = MessageDigest.getInstance("MD5")
            digestInputStream = DigestInputStream(fis, md)
            val buffer = ByteArray(256 * 1024)
            while (true) {
                if (digestInputStream.read(buffer) <= 0) break
            }
            md = digestInputStream.messageDigest
            md.digest()
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
            null
        } catch (e: IOException) {
            e.printStackTrace()
            null
        } finally {
            try {
                fis?.close()
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    private fun bytes2HexString(bytes: ByteArray?): String? {
        if (bytes == null || bytes.isEmpty()) {
            return null
        }
        val stringBuilder = StringBuilder("")
        for (byte in bytes) {
            val v = byte.toInt() and 0xFF
            val hv = Integer.toHexString(v)
            if (hv.length < 2) {
                stringBuilder.append(0)
            }
            stringBuilder.append(hv)
        }
        return stringBuilder.toString()
    }


}
